const _cachedView = new Map();
const _currentView = {};

const _addCacheView = (appMainDom, menu) => {
  _cachedView.set(
    menu.index,
    appMainDom.lastChild && appMainDom.lastChild.cloneNode(true)
  );
};

function appendScript(code) {
  // 创建一个新的 <script> 元素
  var scriptElement = document.createElement("script");

  // 设置 <script> 的 type 属性为 "module"
  scriptElement.type = "module";
  const options = {
    presets: ['es2015', 'react'] 
  };
  // 设置 <script> 的 src 属性，指定要加载的模块文件
  scriptElement.textContent = Babel.transform(code, options).code;

  document.body.appendChild(scriptElement);
};

/*
 * menu: 菜单
 * lastMenu: 上一个菜单，模拟单页应用中的路由跳转，页面间传递参数
 * type: 渲染类型，vue/react/空，这里不建议多模板混用，只能选择其一
 * 注意：
 * 1. 注入的子节点必须有根节点包裹
 * 2. 注入的脚本中，最好使用type="module", 如果需要使用其他类型，请注意命令变量不要冲突
 * 3. 使用index作为class/id的一部分时，最好不要以index开头，index可能是数字
 */
const updateContent = async (menu, lastMenu, forceUpdate) => {
  if (lastMenu && menu.index === lastMenu.index) return;
  NProgress.start();
  switch (menu.templateType) {
    case "vue":
      updateContentByVue(menu, lastMenu, forceUpdate);
      NProgress.done();
      break;
    case "react":
      updateContentByReact(menu, lastMenu, forceUpdate);
      NProgress.done();
      break;
    default:
      updateContentByDom(menu, lastMenu, forceUpdate);
      NProgress.done();
      break;
  }
};

const updateContentByDom = async (menu, lastMenu, forceUpdate) => {
  NProgress.inc();
  const appMainDom = document.querySelector(".app-main");
  let content;
  // 如果已经缓存，直接展示即可
  if (menu.cache && _cachedView.has(menu.index) && !forceUpdate) {
    console.log("使用缓存内容......");
    lastMenu && lastMenu.cache && _addCacheView(appMainDom, lastMenu);
    const fgDom = _cachedView.get(menu.index);
    appMainDom.innerHTML = "";
    appMainDom.appendChild(fgDom);
  } else {
    const id = uuid.v4().replaceAll('-', '');
    content = `
              <script> function con () { alert('hello world'); } </script>

              <div class="template animate__animated animate__fadeInRight" id="${id}">
              
              <div class="box" id="app-main-${menu.index}" style="padding: 7px;"> 
                <h1>测试：内容是原生HTML</h1>
                <h3>参数:</h3>
                <div>menu: ${menu && JSON.stringify(menu)}</div>
                <div>lastMenu: ${lastMenu ? JSON.stringify(lastMenu) : '暂无'}</div>
                <h3>功能:</h3>
                <div>改变背景色：white</div>
                <div>引入JQ，并修改字体颜色：rgb(64,158,255)</div>

                <button onclick="con()" class='app-main-${
                  menu.index
                }-button'>测试按钮</button>

                <h3>注意事项: </h3>
                <a target="_blank" href="https://juejin.cn/post/6916453635702554638">动画不生效：https://juejin.cn/post/6916453635702554638</a>
              </div>
              <script type="module">
                const dom${id} = document.querySelector("#app-main-${menu.index}");
                dom${id}.style.backgroundColor = 'white';
                window.console.log('hell');

                // 引入JQ并使用
                function callback() { $('#app-main-${menu.index} h3').css({ 'color': 'rgb(64,158,255)' }); }
                loadScript('https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.js', callback); // loadScript是全局公共方法，使用方式Fn(url, callback)

                // 使用完或者不需要使用时，目前只能迷惑性的在HTML中不显示，但实际已经装载，$依旧可以全局使用
                // 如果不想被使用，可以强制置空，$ = null;
                unloadScript('https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.js');
              </script>
              <style>
                #app-main-${menu.index} {
                  line-height: 40px;
                }
              <style>
              </div>

              
              `;
    // content = pageRender(menu);
    lastMenu && lastMenu.cache && _addCacheView(appMainDom, lastMenu);
    const fragDOM = document.createRange().createContextualFragment(content);
    appMainDom.innerHTML = "";
    appMainDom.appendChild(fragDOM);
  }
};

const updateContentByVue = async (menu, lastMenu) => {
  NProgress.inc();
  const appMainDom = document.querySelector(".app-main");
  let content;
  // 如果已经缓存，直接展示即可
  if (menu.cache && _cachedView.has(menu.index) && !forceUpdate) {
    console.log("使用缓存内容......");
    lastMenu && lastMenu.cache && _addCacheView(appMainDom, lastMenu);
    const fgDom = _cachedView.get(menu.index);
    appMainDom.innerHTML = "";
    appMainDom.appendChild(fgDom);
  } else {
    content = pageRender(menu);
    lastMenu && lastMenu.cache && _addCacheView(appMainDom, lastMenu);
    const fragDOM = document.createRange().createContextualFragment(content);
    appMainDom.innerHTML = "";
    appMainDom.appendChild(fragDOM);
  }
};

const updateContentByReact = async (menu, lastMenu) => {
  NProgress.inc();
  const appMainDom = document.querySelector(".app-main");
  let content;
  // 如果已经缓存，直接展示即可
  if (menu.cache && _cachedView.has(menu.index) && !forceUpdate) {
    console.log("使用缓存内容......");
    lastMenu && lastMenu.cache && _addCacheView(appMainDom, lastMenu);
    const fgDom = _cachedView.get(menu.index);
    appMainDom.innerHTML = "";
    appMainDom.appendChild(fgDom);
  } else {
    console.log("请求接口......");
    content = `
    <div class="box" id="app-main-${menu.index}"> </div>
    `;
    const code = `   
    const CommonA = ()=>{
      return <a>React JSX 语法创建</a>
    }
    console.log(CommonA)
    ReactDOM.render(<CommonA />, document.getElementById("app-main-${menu.index}"));
    `;

    appendScript(code);
    // content = `
    //   <div class="box" id="app-main-${menu.index}"> </div>
    //   <script type="module">
    //     const header = React.createElement("header", null, React.createElement("h1", null, "React API语法创建"));
    //     ReactDOM.render(header, document.querySelector("#app-main-${menu.index}"));
    //   </script> 
    //   `;
    // _cachedView.set(menu.id, content);
  }
  const fragDOM = document.createRange().createContextualFragment(content);
  appMainDom.innerHTML = "";
  appMainDom.appendChild(fragDOM);
};



